import sounddevice as sd
import soundfile as sf
import whisper
import webrtcvad
import numpy as np

def record_audio_vad(filename="temp.wav", samplerate=16000, max_record=20, vad_mode=2, silence_limit=0.8):
    """
    使用VAD自动检测说话结束，自动停止录音。
    :param filename: 保存录音的文件名
    :param samplerate: 采样率
    :param max_record: 最大录音时长（秒）
    :param vad_mode: VAD灵敏度（0-3，越大越严格）
    :param silence_limit: 静音判定时长（秒）
    """
    try:
        vad = webrtcvad.Vad(vad_mode)  # 创建VAD对象
        frame_duration = 30  # 每帧时长(ms)
        frame_size = int(samplerate * frame_duration / 1000)  # 每帧采样点数
        audio_buffer = []  # 用于存储录音数据
        silence_count = 0  # 静音帧计数
        max_frames = int(max_record * 1000 / frame_duration)  # 最大帧数
        print("请开始说话...（停顿约1秒自动结束）")
        stream = sd.InputStream(samplerate=samplerate, channels=1, dtype='int16')
        with stream:
            for i in range(max_frames):
                frame, _ = stream.read(frame_size)  # 读取一帧音频
                frame_bytes = frame.tobytes()
                is_speech = vad.is_speech(frame_bytes, samplerate)  # 判断是否为语音
                audio_buffer.append(frame)
                if not is_speech:
                    silence_count += 1  # 静音帧+1
                else:
                    silence_count = 0  # 有语音则重置
                # 连续静音达到阈值且已录入一定帧数，判定说话结束
                if silence_count * frame_duration > silence_limit * 1000 and i > 10:
                    break
        audio_np = np.concatenate(audio_buffer, axis=0)  # 合并所有帧
        sf.write(filename, audio_np, samplerate)  # 保存为wav文件
        print("录音结束。")
    except Exception as e:
        print(f"录音异常: {e}")

def transcribe_audio(filename="temp.wav", model_name="base"):
    """
    使用Whisper模型进行语音识别。
    :param filename: 录音文件名
    :param model_name: Whisper模型名
    :return: 识别文本
    """
    try:
        print("加载Whisper模型...")
        model = whisper.load_model(model_name)
        print("开始识别...")
        result = model.transcribe(filename, language=None)
        print("识别完成。")
        return result["text"]
    except Exception as e:
        print(f"ASR识别异常: {e}")
        return ""

def record_and_transcribe():
    """
    录音并自动识别，返回识别文本。
    """
    record_audio_vad()
    return transcribe_audio() 